package fr.inserm.umr915.libjson.bdb;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

import com.sleepycat.bind.tuple.TupleInput;
import com.sleepycat.bind.tuple.TupleOutput;
import com.sleepycat.je.DatabaseEntry;

import fr.inserm.umr915.libjson.Node;
import fr.inserm.umr915.libjson.NodeFactory;

/**
 * 
 * GZipNodeBinding
 *
 */
public class GZipNodeBinding
	extends AbstractNodeBinding
	{
	private NodeBinding nodeBinding;

	public GZipNodeBinding(NodeFactory factory)
		{
		this.nodeBinding=new NodeBinding(factory);
		}
	
	public GZipNodeBinding()
		{
		this(new NodeFactory());
		}
	
	@Override
	public Node entryToObject(DatabaseEntry entry)
		{
		try
			{
			DataInputStream dis=new DataInputStream(
				new GZIPInputStream(new ByteArrayInputStream(
					entry.getData(),entry.getOffset(),entry.getSize())));
			Node n= this.nodeBinding.getNodeFactory().read(dis);
			dis.close();
			return n;
			}
		catch (IOException e)
			{
			throw new RuntimeException(e);
			}
		}
	
	@Override
	public void objectToEntry(Node object, DatabaseEntry entry)
		{
		try {
			ByteArrayOutputStream baos=new ByteArrayOutputStream();
			GZIPOutputStream zout=new GZIPOutputStream(baos);
			DataOutputStream daos=new DataOutputStream(zout);
			object.write(daos);
			daos.flush();
			zout.finish();
			zout.flush();
			zout.close();
			entry.setData(baos.toByteArray());
			} 
		catch (Exception e)
			{
			throw new RuntimeException(e);
			}
		
		}
	
	@Override
	public Node entryToObject(TupleInput in)	
		{
		try
		{
		DataInputStream dis=new DataInputStream(
			new GZIPInputStream(in));
		Node n= this.nodeBinding.getNodeFactory().read(dis);
		dis.close();
		return n;
		}
	catch (IOException e)
		{
		throw new RuntimeException(e);
		}
		}

	@Override
	public void objectToEntry(Node node, TupleOutput out)
		{
		try {
			GZIPOutputStream zout=new GZIPOutputStream(out);
			DataOutputStream daos=new DataOutputStream(zout);
			node.write(daos);
			daos.flush();
			zout.finish();
			zout.flush();
			zout.close();
			daos.close();
			} 
		catch (Exception e)
			{
			throw new RuntimeException(e);
			}
		}

	}
